/**
  ******************************************************************************
  * @file    Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and 
  *          peripherals interrupt service routine.
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTI
  
  AL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include <stdio.h>
#include <string.h> 
#include "bsp_SysTick.h"
#include "bsp_esp8266.h"
#include "bsp_esp8266_test.h"
#include "bsp_usart.h"
#include "bsp_dht11.h"
#include "bsp_key.h"
#include "flash.h"
#include "Storage_Adapter.h"
#include "common.h"
#include "timedate.h"
#include "bsp_ec800m.h"


#define TASK_DELAY_NUM  3       //总任务个数，可以自己根据实际情况修改
#define TASK_DELAY_0    500    //任务0延时 500*10 毫秒后执行：读取 DHT11 传感器数据
#define TASK_DELAY_1    1     //任务1延时 1*10 毫秒后执行：按键检测
#define TASK_DELAY_2    50     //任务2延时 50*10 毫秒后执行：

uint32_t Task_Delay_Group[TASK_DELAY_NUM];  //任务数组，用来计时、并判断是否执行对应任务

/* 读传感器数据完成标志 */
// - 标志置 1表示完成读取，在主循环处理数据
// - 标志置 0表示未完成读取
// - 标志置-1表示读取错误
int read_dht11_finish;

// 按键按下标志
volatile uint8_t key_pressed = 0; // 按键按下标志

// 外部变量
extern DHT11_Data_TypeDef DHT11_Data;


/** @addtogroup STM32F10x_StdPeriph_Template
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
  * @brief  This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
void SVC_Handler(void)
{
}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  This function handles PendSVC exception.
  * @param  None
  * @retval None
  */
void PendSV_Handler(void)
{
}

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
  int i;
  Flash_Status_TypeDef flash_status;
  
  // 确保TASK_DELAY_NUM不为0且不超过合理范围
  if(TASK_DELAY_NUM > 0 && TASK_DELAY_NUM <= 10)
  {
    for(i=0; i<TASK_DELAY_NUM; i++)
    {
      Task_Delay_Group[i] ++;                   //任务计时，时间到后执行
    }
    
    /* 处理任务0 */
    if(Task_Delay_Group[0] >= TASK_DELAY_0)     //判断是否执行任务0
    {
      Task_Delay_Group[0] = 0;                  //置0重新计时
      
      /* 任务0：读取 DHT11 传感器数据 */
      if( ! read_dht11_finish )
      {
        if ( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS ) //读取 DHT11 温湿度信息
        {
          read_dht11_finish = 1; //读取完成
          
          /* 将DHT11数据存储到W25Q64 */
          Storage_Status_TypeDef storage_status = DHT11_Storage_SaveData(&DHT11_Data);
          if(storage_status == STORAGE_SUCCESS)
          {
            // 存储成功，可以在这里添加指示灯或串口输出
             printf("DHT11数据已存储到W25Q64，记录数：%d\r\n", DHT11_Storage_GetRecordCount());
          }
          else if(storage_status == STORAGE_FULL)
          {
            // W25Q64存储空间已满
             printf("W25Q64存储空间已满！\r\n");
          }
          else
          {
            // 存储失败
             printf("W25Q64存储失败！错误码：%d\r\n", storage_status);
          }
        }
        else
        {
          read_dht11_finish = -1; //读取错误
        }
      }
    }
    
    /* 处理任务1 */
    if(Task_Delay_Group[1] >= TASK_DELAY_1)     //判断是否执行任务1
    {
      Task_Delay_Group[1] = 0;                  //置0重新计时
      
      /* 任务1：按键检测 */
      if(KEY_Scan_NonBlocking(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON)
      {
        key_pressed = 1;  // 设置按键按下标志
      }
    }
    
    /* 处理任务2 */
    if(Task_Delay_Group[2] >= TASK_DELAY_2)     //判断是否执行任务2
    {
      Task_Delay_Group[2] = 0;                  //置0重新计时
      
      /* 任务2：预留任务 */
      CSTX_4G_RECTCPData();//收数据,接收服务器下发的数据并打印到串口1进行显示
    }
  }
}


/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************/
// 串口中断服务函数
void DEBUG_USART_IRQHandler(void)
{
  uint8_t ucCh;
	if ( USART_GetITStatus ( DEBUG_USARTx, USART_IT_RXNE ) != RESET )
	{
		ucCh  = USART_ReceiveData( DEBUG_USARTx );
		
		if ( strUSART_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
			   strUSART_Fram_Record .Data_RX_BUF [ strUSART_Fram_Record .InfBit .FramLength ++ ]  = ucCh;

	}
	 	 
	if ( USART_GetITStatus( DEBUG_USARTx, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕
	{
    strUSART_Fram_Record .InfBit .FramFinishFlag = 1;		
		
		// 正确清除IDLE中断标志位：先读SR寄存器（已通过USART_GetITStatus读取），再读DR寄存器
		// 但是要保存DR中的数据，不能丢弃
		if(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == SET)
		{
			ucCh = USART_ReceiveData( DEBUG_USARTx );
			// 如果DR中还有数据，保存到缓冲区
			if ( strUSART_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )
				strUSART_Fram_Record .Data_RX_BUF [ strUSART_Fram_Record .InfBit .FramLength ++ ]  = ucCh;
		}
		else
		{
			// 如果DR中没有数据，只是为了清除IDLE标志位而读取
			ucCh = USART_ReceiveData( DEBUG_USARTx );
		}
  }	
}
/**
  * @brief  This function handles macESP8266_USARTx Handler.
  * @param  None
  * @retval None
  */
void macESP8266_USART_INT_FUN ( void )
{	
	uint8_t ucCh;
	
	if ( USART_GetITStatus ( macESP8266_USARTx, USART_IT_RXNE ) != RESET )
	{
		ucCh  = USART_ReceiveData( macESP8266_USARTx );
		
		if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
			   strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;

	}
	 	 
	if ( USART_GetITStatus( macESP8266_USARTx, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕
	{
    strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;
		
		// 正确清除IDLE中断标志位：先读SR寄存器（已通过USART_GetITStatus读取），再读DR寄存器
		// 但是要保存DR中的数据，不能丢弃
		if(USART_GetFlagStatus(macESP8266_USARTx, USART_FLAG_RXNE) == SET)
		{
			ucCh = USART_ReceiveData( macESP8266_USARTx );
			// 如果DR中还有数据，保存到缓冲区
			if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )
				strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;
		}
		else
		{
			// 如果DR中没有数据，只是为了清除IDLE标志位而读取
			ucCh = USART_ReceiveData( macESP8266_USARTx );
		}
	
		ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
		
  }	

}

/**
  * @brief  This function handles USART2 interrupt request (for EC800M module).
  * @param  None
  * @retval None
  */
void USART2_IRQHandler(void)
{
    uint8_t ucCh;
    extern UART_BUF EC800M_BUF;  // 声明外部变量
    
    if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        ucCh = USART_ReceiveData(USART2);
        
        if (EC800M_BUF.index < (BUFLEN - 1))  // 预留1个字节写结束符
        {
            EC800M_BUF.buf[EC800M_BUF.index++] = ucCh;
            EC800M_BUF.buf[EC800M_BUF.index] = '\0';  // 添加字符串结束符
        }
    }
    
    if (USART_GetITStatus(USART2, USART_IT_IDLE) == SET)  // 数据帧接收完毕
    {
        // 调试输出：显示完整接收到的数据帧
//        if (EC800M_BUF.index > 0) {
//            printf("完整的数据帧: %s\r\n", EC800M_BUF.buf);
//        }
        
        // 正确清除IDLE中断标志位：先读SR寄存器（已通过USART_GetITStatus读取），再读DR寄存器
        if(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET)
        {
            ucCh = USART_ReceiveData(USART2);
            
            // 如果DR中还有数据，保存到缓冲区
            if (EC800M_BUF.index < (BUFLEN - 1))
            {
                EC800M_BUF.buf[EC800M_BUF.index++] = ucCh;
                EC800M_BUF.buf[EC800M_BUF.index] = '\0';
            }
        }
        else
        {
            // 如果DR中没有数据，只是为了清除IDLE标志位而读取
            ucCh = USART_ReceiveData(USART2);
        }
        
        // 数据帧接收完毕，清空缓冲区准备下一次接收
        // 注意：这里我们不清空缓冲区，让其他函数处理完数据后再清空
    }
}

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
/*void PPP_IRQHandler(void)
{
}*/

/**
  * @}
  */ 


/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
